#ifndef CAMERA_HPP
#define CAMERA_HPP

#include "config.hpp"
#include "opencv2/opencv.hpp"
#include <thread>
#include <mutex>
#include <atomic>

/**
 * 相机类 - 提供线程安全的相机操作
 * 
 * 该类封装了OpenCV的VideoCapture，并添加了线程安全机制
 * 使用单独的线程进行图像采集，避免主线程在等待相机帧时阻塞
 * 通过互斥锁和原子变量确保线程间安全地共享图像数据
 */
class Camera {
public:
    /**
     * 构造函数
     * @param index 相机设备索引，默认为0（通常是系统默认相机）
     */
    explicit Camera(int index = 0);
    
    /**
     * 析构函数
     * 确保在对象销毁时停止采集线程并释放相机资源
     */
    ~Camera();

    // -------- 相机控制方法 --------
    /**
     * 打开相机设备并根据配置设置参数
     * @param config 应用程序配置对象
     * @return 成功返回true，失败返回false
     */
    bool open(const AppConfig& config);
    
    /**
     * 启动图像采集线程
     * 在后台持续从相机获取图像并更新共享缓冲区
     */
    void start();
    
    /**
     * 停止图像采集线程
     * 安全地终止线程并等待其完成
     */
    void stop();

    // -------- 数据访问方法 --------
    /**
     * 检查相机是否成功打开
     * @return 相机已打开返回true，否则返回false
     */
    bool isOpened() const;
    
    /**
     * 从共享缓冲区读取最新的图像帧
     * 这是一个线程安全的操作，会等待直到有新帧可用
     * @param frame 用于存储读取到的图像帧的Mat对象引用
     * @return 成功读取返回true，失败返回false
     */
    bool read(cv::Mat& frame);

private:
    /**
     * 图像采集循环函数
     * 在单独的线程中运行，持续从相机获取图像并更新共享缓冲区
     */
    void captureLoop();

    // -------- 相机设备 --------
    cv::VideoCapture cap;     // OpenCV相机捕获对象
    int camera_index;         // 相机设备索引

    // -------- 线程管理 --------
    std::thread capture_thread;    // 图像采集线程
    std::atomic<bool> is_running;  // 线程运行状态标志（原子变量确保线程间可见性）

    // -------- 共享数据和同步机制 --------
    std::mutex frame_mutex;           // 保护共享帧的互斥锁
    cv::Mat shared_frame;             // 最新捕获的图像帧（在线程间共享）
    std::atomic<bool> new_frame_available;  // 新帧可用标志（原子变量确保线程间可见性）
};

#endif //CAMERA_HPP